package com.ruoyi.disk.service.impl;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.disk.domain.SysBackup;
import com.ruoyi.disk.domain.SysBackupFile;
import com.ruoyi.disk.domain.SysFile;
import com.ruoyi.disk.domain.SysStorage;
import com.ruoyi.disk.domain.dto.RestoreDTO;
import com.ruoyi.disk.domain.vo.BackupFileVO;
import com.ruoyi.disk.domain.vo.BackupVO;
import com.ruoyi.disk.domain.vo.RestoreResultVO;
import com.ruoyi.disk.mapper.SysBackupFileMapper;
import com.ruoyi.disk.mapper.SysBackupMapper;
import com.ruoyi.disk.mapper.SysFileMapper;
import com.ruoyi.disk.mapper.SysStorageMapper;
import com.ruoyi.disk.service.ISysBackupService;

/**
 * 备份服务实现
 */
@Service
public class SysBackupServiceImpl implements ISysBackupService {
    private static final Logger log = LoggerFactory.getLogger(SysBackupServiceImpl.class);
    
    @Autowired
    private SysBackupMapper sysBackupMapper;
    
    @Autowired
    private SysBackupFileMapper sysBackupFileMapper;
    
    @Autowired
    private SysFileMapper sysFileMapper;
    
    @Autowired
    private SysStorageMapper sysStorageMapper;

    /**
     * 创建用户磁盘备份
     */
    @Override
    @Transactional
    public BackupVO createBackup(Long userId) {
        // 检查权限
        if (!SecurityUtils.isAdmin() && !userId.equals(SecurityUtils.getUserId())) {
            throw new ServiceException("没有权限备份其他用户的文件");
        }
        
        // 获取用户存储信息
        SysStorage storage = sysStorageMapper.selectSysStorageByUserId(userId);
        if (storage == null) {
            throw new ServiceException("用户存储信息不存在");
        }
        
        // 创建备份记录
        String backupId = UUID.randomUUID().toString().replace("-", "");
        Date now = DateUtils.getNowDate();
        
        SysBackup backup = new SysBackup();
        backup.setBackupId(backupId);
        backup.setUserId(userId);
        backup.setBackupTime(now);
        backup.setStatus("1"); // 备份中
        backup.setCreateBy(SecurityUtils.getUsername());
        backup.setCreateTime(now);
        sysBackupMapper.insertSysBackup(backup);
        
        try {
            // 获取用户所有文件
            SysFile queryFile = new SysFile();
            queryFile.setCreateId(userId);
            queryFile.setDelFlag("0"); // 未删除的
            List<SysFile> files = sysFileMapper.selectSysFileList(queryFile);
            
            long totalSize = 0;
            List<SysBackupFile> backupFiles = new ArrayList<>();
            
            // 创建备份目录
            String backupDir = FileUploadUtils.getDefaultBaseDir() + "backup/" + userId + "/" + backupId + "/";
            File dir = new File(backupDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            // 备份每个文件
            for (SysFile file : files) {
                String filePath = file.getFilePath();
                if (StringUtils.isEmpty(filePath)) {
                    continue;
                }
                
                File sourceFile = new File(filePath);
                if (!sourceFile.exists() || !sourceFile.isFile()) {
                    continue;
                }
                
                // 计算备份路径
                String fileName = sourceFile.getName();
                String backupPath = backupDir + fileName;
                
                // 复制文件到备份目录
                File destFile = new File(backupPath);
                FileUtils.copyFile(sourceFile, destFile);
                
                // 创建备份文件记录
                SysBackupFile backupFile = new SysBackupFile();
                backupFile.setBackupId(backupId);
                backupFile.setFileId(file.getId());
                backupFile.setFileName(file.getFileName());
                backupFile.setFilePath(file.getFilePath());
                backupFile.setFileSize(file.getFileSize());
                backupFile.setBackupPath(backupPath);
                backupFile.setBackupTime(now);
                backupFile.setCreateBy(SecurityUtils.getUsername());
                backupFile.setCreateTime(now);
                
                backupFiles.add(backupFile);
                totalSize += file.getFileSize();
            }
            
            // 批量插入备份文件记录
            if (!backupFiles.isEmpty()) {
                sysBackupFileMapper.batchInsertSysBackupFile(backupFiles);
            }
            
            // 更新备份记录
            backup.setFileCount(backupFiles.size());
            backup.setBackupSize(totalSize);
            backup.setStatus("0"); // 正常
            backup.setUpdateBy(SecurityUtils.getUsername());
            backup.setUpdateTime(DateUtils.getNowDate());
            sysBackupMapper.updateSysBackup(backup);
            
            // 返回备份信息
            BackupVO vo = new BackupVO();
            vo.setBackupId(backupId);
            vo.setBackupTime(backup.getBackupTime());
            vo.setFileCount(backup.getFileCount());
            vo.setBackupSize(backup.getBackupSize());
            
            return vo;
        } catch (Exception e) {
            log.error("创建备份失败", e);
            
            // 更新备份状态为失败
            backup.setStatus("2"); // 备份失败
            backup.setRemark("备份失败: " + e.getMessage());
            backup.setUpdateBy(SecurityUtils.getUsername());
            backup.setUpdateTime(DateUtils.getNowDate());
            sysBackupMapper.updateSysBackup(backup);
            
            throw new ServiceException("创建备份失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户的备份列表
     */
    @Override
    public List<BackupVO> listUserBackups(Long userId) {
        // 检查权限
        if (!SecurityUtils.isAdmin() && !userId.equals(SecurityUtils.getUserId())) {
            throw new ServiceException("没有权限查看其他用户的备份");
        }
        
        // 查询备份列表
        List<SysBackup> backups = sysBackupMapper.selectSysBackupListByUserId(userId);
        
        // 转换为VO
        return backups.stream().map(backup -> {
            BackupVO vo = new BackupVO();
            vo.setBackupId(backup.getBackupId());
            vo.setBackupTime(backup.getBackupTime());
            vo.setFileCount(backup.getFileCount());
            vo.setBackupSize(backup.getBackupSize());
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 获取备份文件列表
     */
    @Override
    public List<BackupFileVO> listBackupFiles(Long userId, String backupId) {
        // 检查权限
        if (!SecurityUtils.isAdmin() && !userId.equals(SecurityUtils.getUserId())) {
            throw new ServiceException("没有权限查看其他用户的备份文件");
        }
        
        // 查询备份
        SysBackup backup = sysBackupMapper.selectSysBackupById(backupId);
        if (backup == null || !backup.getUserId().equals(userId)) {
            throw new ServiceException("备份不存在或者不属于指定用户");
        }
        
        // 查询备份文件列表
        List<SysBackupFile> backupFiles = sysBackupFileMapper.selectSysBackupFileListByBackupId(backupId);
        
        // 转换为VO
        return backupFiles.stream().map(file -> {
            BackupFileVO vo = new BackupFileVO();
            vo.setFileId(file.getFileId());
            vo.setFileName(file.getFileName());
            vo.setFilePath(file.getFilePath());
            vo.setFileSize(file.getFileSize());
            vo.setBackupTime(file.getBackupTime());
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 从备份恢复文件
     */
    @Override
    @Transactional
    public RestoreResultVO restoreFiles(RestoreDTO restoreDTO) {
        Long userId = restoreDTO.getUserId();
        String backupId = restoreDTO.getBackupId();
        List<String> fileIds = restoreDTO.getFileIds();
        
        // 检查权限
        if (!SecurityUtils.isAdmin() && !userId.equals(SecurityUtils.getUserId())) {
            throw new ServiceException("没有权限恢复其他用户的文件");
        }
        
        // 查询备份
        SysBackup backup = sysBackupMapper.selectSysBackupById(backupId);
        if (backup == null || !backup.getUserId().equals(userId)) {
            throw new ServiceException("备份不存在或者不属于指定用户");
        }
        
        RestoreResultVO result = new RestoreResultVO();
        List<RestoreResultVO.RestoreDetail> details = new ArrayList<>();
        int successCount = 0;
        int failedCount = 0;
        
        for (String fileId : fileIds) {
            RestoreResultVO.RestoreDetail detail = new RestoreResultVO.RestoreDetail();
            detail.setFileId(fileId);
            
            try {
                // 查询备份文件
                SysBackupFile backupFile = sysBackupFileMapper.selectSysBackupFileByFileId(backupId, fileId);
                if (backupFile == null) {
                    detail.setStatus("failed");
                    detail.setMessage("备份文件不存在");
                    details.add(detail);
                    failedCount++;
                    continue;
                }
                
                // 检查原文件是否存在
                SysFile sysFile = sysFileMapper.selectSysFileById(fileId);
                String destPath;
                
                if (sysFile != null) {
                    // 如果原文件存在，重命名为原文件名_恢复的_时间戳
                    String origFileName = sysFile.getFileName();
                    String fileNameWithoutExt = StringUtils.substringBeforeLast(origFileName, ".");
                    String ext = StringUtils.substringAfterLast(origFileName, ".");
                    String newFileName = fileNameWithoutExt + "_恢复的_" + System.currentTimeMillis() + 
                                        (StringUtils.isNotEmpty(ext) ? "." + ext : "");
                    
                    // 确定目标路径
                    destPath = StringUtils.substringBeforeLast(sysFile.getFilePath(), "/") + "/" + newFileName;
                } else {
                    // 如果原文件不存在，使用原来的文件路径
                    destPath = backupFile.getFilePath();
                    
                    // 重新创建文件记录
                    sysFile = new SysFile();
                    sysFile.setId(fileId);
                    sysFile.setFileName(backupFile.getFileName());
                    sysFile.setFilePath(destPath);
                    sysFile.setFileSize(backupFile.getFileSize());
                    sysFile.setCreateId(userId);
                    sysFile.setCreateBy(SecurityUtils.getUsername());
                    sysFile.setCreateTime(DateUtils.getNowDate());
                    sysFile.setDelFlag("0");
                    
                    sysFileMapper.insertSysFile(sysFile);
                }
                
                // 复制备份文件到目标路径
                File sourceFile = new File(backupFile.getBackupPath());
                File destFile = new File(destPath);
                
                // 确保目标目录存在
                destFile.getParentFile().mkdirs();
                
                FileUtils.copyFile(sourceFile, destFile);
                
                detail.setStatus("success");
                detail.setMessage("恢复成功");
                successCount++;
            } catch (Exception e) {
                log.error("恢复文件失败: {}", fileId, e);
                detail.setStatus("failed");
                detail.setMessage("恢复失败: " + e.getMessage());
                failedCount++;
            }
            
            details.add(detail);
        }
        
        result.setSuccessCount(successCount);
        result.setFailedCount(failedCount);
        result.setDetails(details);
        
        return result;
    }

    /**
     * 查询备份列表
     */
    @Override
    public List<SysBackup> selectSysBackupList(SysBackup sysBackup) {
        return sysBackupMapper.selectSysBackupList(sysBackup);
    }

    /**
     * 查询备份详细信息
     */
    @Override
    public SysBackup selectSysBackupById(String backupId) {
        return sysBackupMapper.selectSysBackupById(backupId);
    }

    /**
     * 新增备份
     */
    @Override
    public int insertSysBackup(SysBackup sysBackup) {
        sysBackup.setCreateTime(DateUtils.getNowDate());
        return sysBackupMapper.insertSysBackup(sysBackup);
    }

    /**
     * 修改备份
     */
    @Override
    public int updateSysBackup(SysBackup sysBackup) {
        sysBackup.setUpdateTime(DateUtils.getNowDate());
        return sysBackupMapper.updateSysBackup(sysBackup);
    }

    /**
     * 删除备份
     */
    @Override
    @Transactional
    public int deleteSysBackupById(String backupId) {
        // 删除备份文件记录
        sysBackupFileMapper.deleteSysBackupFileByBackupId(backupId);
        
        // 删除备份记录
        return sysBackupMapper.deleteSysBackupById(backupId);
    }

    /**
     * 批量删除备份
     */
    @Override
    @Transactional
    public int deleteSysBackupByIds(String[] backupIds) {
        // 删除备份文件记录
        for (String backupId : backupIds) {
            sysBackupFileMapper.deleteSysBackupFileByBackupId(backupId);
        }
        
        // 删除备份记录
        return sysBackupMapper.deleteSysBackupByIds(backupIds);
    }
} 